package com.ljf.weixin;

import com.ljf.framework.context.LjfContextManager;
import com.ljf.framework.filter.LjfAbstractFilter;
import com.ljf.framework.filter.LjfFilterAuthStrategy;
import com.ljf.framework.router.LjfRouter;
import com.ljf.framework.router.LjfRouterManager;
import com.ljf.framework.security.token.LjfTokenManager;
import com.ljf.framework.util.LjfJsonUtil;
import com.ljf.weixin.vo.Code2SessionVO;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
 * 说明：
 *
 * @Auther: lijinfeng
 * @Date: 2024/5/21
 */

public class WeiXinFilter extends LjfAbstractFilter {

    @Override
    public List<String> getIncludeList() {
        return Collections.singletonList(WeiXinManager.getConfig().getLoginUrl());
    }

    @Override
    public LjfFilterAuthStrategy getBeforeAuthStrategy() {
        return r -> WeiXinManager.getConfig().isOpen();
    }

    @Override
    public LjfFilterAuthStrategy getAuthStrategy() {
        return r -> {
            System.out.println("WeiXinFilter");
            String code = (String) LjfContextManager.getRequest().getAttribute("js_code");
            HashMap<String, String> map = new HashMap<>();
            map.put("appid",WeiXinManager.getConfig().getAppId());
            map.put("secret",WeiXinManager.getConfig().getSecret());
            map.put("grant_type","authorization_code");
            map.put("js_code",code);

            String result = WeiXinManager.doRequest(WeiXinUrlEnum.code2Session, map);

            Code2SessionVO code2SessionVO = new Code2SessionVO();
            try {
                code2SessionVO = LjfJsonUtil.fromJsonStringSimple(Code2SessionVO.class, result);
            } catch (Exception e) {
                System.out.println(result);
                e.printStackTrace();
            }
            long timeout = LjfTokenManager.getLjfTokenConfig().getTimeout();
            System.out.println("token过期时间："+timeout);
            String token = WeiXinManager.doLogin(code2SessionVO.getOpenid(), null, code2SessionVO.getSession_key());
            //  会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全，
            //  开发者服务器不应该把会话密钥下发到小程序，也不应该对外提供这个密钥。
            // 这里将值修改为token供前端使用
            code2SessionVO.setSession_key(token);
            try (PrintWriter writer = LjfContextManager.getResponse().getWriter()) {
                writer.print(LjfJsonUtil.toJsonString(code2SessionVO));
                writer.flush();
            }catch (IOException e){
                e.printStackTrace();
            }
            return false;
        };
    }

    @Override
    public boolean doCusFilter(){
        // 判断是否开启
        if(!WeiXinManager.getConfig().isOpen())
            return true;

        /*
         1. 拦截微信功能的请求
         */

        List<String> loginUrl = Arrays.asList(WeiXinManager.getConfig().getLoginUrl());
        LjfRouter router = LjfRouterManager.createRouter();
        router.match(loginUrl).check(r -> {
            System.out.println("WeiXinFilter");
            String code = (String) LjfContextManager.getRequest().getAttribute("js_code");
            HashMap<String, String> map = new HashMap<>();
            map.put("appid",WeiXinManager.getConfig().getAppId());
            map.put("secret",WeiXinManager.getConfig().getSecret());
            map.put("grant_type","authorization_code");
            map.put("js_code",code);

            String result = WeiXinManager.doRequest(WeiXinUrlEnum.code2Session, map);

            Code2SessionVO code2SessionVO = new Code2SessionVO();
            try {
                code2SessionVO = LjfJsonUtil.fromJsonStringSimple(Code2SessionVO.class, result);
            } catch (Exception e) {
                System.out.println(result);
                e.printStackTrace();
            }
            long timeout = LjfTokenManager.getLjfTokenConfig().getTimeout();
            System.out.println("token过期时间："+timeout);
            String token = WeiXinManager.doLogin(code2SessionVO.getOpenid(), null, code2SessionVO.getSession_key());
            //  会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全，
            //  开发者服务器不应该把会话密钥下发到小程序，也不应该对外提供这个密钥。
            // 这里将值修改为token供前端使用
            code2SessionVO.setSession_key(token);
            try (PrintWriter writer = LjfContextManager.getResponse().getWriter()) {
                writer.print(LjfJsonUtil.toJsonString(code2SessionVO));
                writer.flush();
            }catch (IOException e){
                e.printStackTrace();
            }
        });

        return router.isContinueMatch();
    }

    @Override
    public Integer getOrder() {
        return 30;
    }
}
